package com.sugon.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.sugon.dao.FaultTypeDao;
import com.sugon.entity.FaultTypeEntity;
import com.sugon.service.FaultTypeService;
import com.sugon.utils.MapUtil;
import com.sugon.utils.RRException;
import com.sugon.utils.ShiroUtils;
import com.sugon.utils.YouBianCodeUtil;
import com.sugon.utils.excel.ExcelImport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 故障类型Service实现类
 *
 * @author sugon
 * @date 2019-07-11 10:11:38
 */
@Service("faultTypeService")
public class FaultTypeServiceImpl implements FaultTypeService {

    @Autowired
    private FaultTypeDao faultTypeDao;

    /**
     * 找出指定父类型下的
     *
     * @param typePid
     * @return
     */
    private String buildTreeCode(String typePid) {
        // 声明树编码
        String treeCode;
        /**
         * 找同类，分成三种情况
         * 1.数据库无数据 调用YouBianCodeUtil.getNextYouBianCode(null);
         * 2.添加子节点，无兄弟元素 YouBianCodeUtil.getSubYouBianCode(parentCode,null);
         * 3.添加子节点有兄弟元素 YouBianCodeUtil.getNextYouBianCode(lastCode);
         *
         */
        Map<String, Object> queryParam = cn.hutool.core.map.MapUtil.newHashMap();
        queryParam.put("typePid", typePid);
        List<FaultTypeEntity> faultTypeList = queryList(queryParam);
        if (CollectionUtil.isEmpty(faultTypeList)) {
            if (ROOT_PID_VALUE.equals(typePid)) {
                //情况1
                treeCode = YouBianCodeUtil.getNextYouBianCode(null);
            } else {
                //情况2
                FaultTypeEntity parent = queryObject(typePid);
                treeCode = YouBianCodeUtil.getSubYouBianCode(parent.getTreeCode(), null);
            }
        } else {
            //情况3
            treeCode = YouBianCodeUtil.getNextYouBianCode(faultTypeList.get(0).getTreeCode());
        }
        return treeCode;
    }

    /**
     * queryObject
     *
     * @param id 主键
     * @return
     */
    @Override
    public FaultTypeEntity queryObject(String id) {
        return faultTypeDao.queryObject(id);
    }

    /**
     * queryList
     *
     * @param map 参数
     * @return
     */
    @Override
    public List<FaultTypeEntity> queryList(Map<String, Object> map) {
        MapUtil.removeEmptyValue(map);
        return faultTypeDao.queryList(map);
    }

    @Override
    public List<FaultTypeEntity> queryList(Integer category, String faultCode, String typeName) {
        Map<String, Object> param = cn.hutool.core.map.MapUtil.newHashMap();
        if (StrUtil.isNotEmpty(typeName)) {
            param.put("typeName", typeName);
        }
        if (StrUtil.isNotEmpty(faultCode)) {
            param.put("faultCode", faultCode);
        }
        if (category != null) {
            param.put("category", category);
        }
        return queryList(param);
    }

    @Override
    public FaultTypeEntity queryOrCreateIfNotExists(Integer category, String typePid, String faultCode, String typeName, String remark) {
        List<FaultTypeEntity> faultTypeList = queryList(category, faultCode, null);
        if (CollectionUtil.isNotEmpty(faultTypeList)) {
            return faultTypeList.get(0);
        } else {
            FaultTypeEntity faultType = new FaultTypeEntity();
            faultType.setCategory(category);
            faultType.setTypePid(typePid);
            faultType.setFaultCode(faultCode);
            faultType.setTypeName(typeName);
            faultType.setRemark(remark);
            save(faultType);
            return faultType;
        }
    }

    /**
     * queryTotal
     *
     * @param map 参数
     * @return
     */
    @Override
    public int queryTotal(Map<String, Object> map) {
        return faultTypeDao.queryTotal(map);
    }

    /**
     * queryPidList
     *
     * @param id
     * @return
     */
    @Override
    public List<String> queryPidList(String id) {
        return faultTypeDao.queryPidList(id);
    }

    /**
     * save
     *
     * @param faultType 实体
     * @return
     */
    @Override
    public int save(FaultTypeEntity faultType) {
        setFaultTypeCode(faultType);
        faultType.setDelFlag(1);
        faultType.setId(RandomUtil.randomString(32));
        faultType.setTreeCode(buildTreeCode(faultType.getTypePid()));
        faultType.setCreateUser(ShiroUtils.getUserId());
        faultType.setCreateDate(new Date());
        return faultTypeDao.save(faultType);
    }

    /**
     * 设置故障类别编码
     *
     * @param faultType
     */
    private void setFaultTypeCode(FaultTypeEntity faultType) {
        // 设置故障编码
        String pid = faultType.getTypePid();
        if (StrUtil.isNotEmpty(pid)) {
            FaultTypeEntity parentFaultType = queryObject(pid);
            if (parentFaultType != null) {
                int num = 1;
                String faultCodePrefix = parentFaultType.getFaultCode();
                Integer category = faultType.getCategory();
                String lastestModuleCode = faultTypeDao.getLastestFaultCode(faultCodePrefix, parentFaultType.getCategory());
                if (category == 1) {
                    // 处理设备
                    if (StrUtil.isNotEmpty(lastestModuleCode)) {
                        num += Integer.parseInt(lastestModuleCode.replace(faultCodePrefix, ""));
                    }
                    faultType.setFaultCode(faultCodePrefix + String.format("%02d", num));
                } else if (category == 2) {
                    faultType.setFaultCode(Integer.parseInt(lastestModuleCode) + 1 + "");
                }
            }
        }
    }

    /**
     * update
     *
     * @param faultType 实体
     * @return
     */
    @Override
    public int update(FaultTypeEntity faultType) {
        // 如果故障类型的新老父类型不一样，那么需要重新设置下树编码
        FaultTypeEntity old = queryObject(faultType.getId());
        Assert.notNull(old);
        String old_pid = old.getTypePid();
        String new_pid = faultType.getTypePid();
        if (!new_pid.equals(old_pid)) {
            faultType.setTreeCode(buildTreeCode(new_pid));
        }
        // 设置更新信息
        faultType.setUpdateUser(ShiroUtils.getUserId());
        faultType.setUpdateDate(new Date());
        return faultTypeDao.update(faultType);
    }

    /**
     * updateDel
     *
     * @param id
     * @return
     */
    @Override
    public int updateDel(String id) {
        return faultTypeDao.updateDel(id);
    }

    /**
     * delete
     *
     * @param id
     * @return
     */
    @Override
    public int delete(String id) {
        return faultTypeDao.delete(id);
    }

    /**
     * deleteBatch
     *
     * @param ids
     * @return
     */
    @Override
    public int deleteBatch(String[] ids) {
        return faultTypeDao.deleteBatch(ids);
    }

    /**
     * importE
     *
     * @param file
     * @return
     * @throws Exception
     */
    @Override
    public String importE(MultipartFile file) throws Exception {
        String err = "";
        if (file.isEmpty()) {
            throw new RRException("上传文件不能为空");
        }
        List list = ExcelImport.getExcelData(file);
        if (list != null && list.size() != 0) {
            String[] header = new String[]{"ID", "PID", "故障名称", "备注"};
            String[] data = (String[]) list.get(0);
            int j = 0;
            for (String d : data) {
                if (header[j].equals(d.trim())) {
                    j++;
                }
            }
            if (j < header.length) {
                err = "找不到\"" + header[j] + "\"这一列";
            }
            if (err.equals("")) {
                for (int i = 1; i < list.size(); i++) {
                    FaultTypeEntity faultType = new FaultTypeEntity();
                    faultType.setValues((String[]) list.get(i));
                    faultTypeDao.save(faultType);
                }
            }
        }
        return err;
    }

}
